﻿using System;
using System.IO;
using nRoute.Components.Composition;
using nRoute.Samples.OfficerXcel.Components;
using nRoute.Samples.OfficerXcel.Model;
using nRoute.Services;
using nRoute.ViewServices.Contracts;

namespace nRoute.Samples.OfficerXcel.Services.Runtime
{
    [MapService(typeof(IWorksheetPersistenceService), InitializationMode = InitializationMode.OnDemand,
        Lifetime = InstanceLifetime.Singleton)]
    public class WorksheetPersistenceService
        : IWorksheetPersistenceService
    {
        private const string DEFAULT_EXT = "xcel";
        private const string DEFAULT_FILTER = "Xcel Files (*.xcel) | *.xcel";

        private readonly IOpenFileViewService _openFileViewService;
        private readonly ISaveFileViewService _saveFileViewService;
        private readonly IApplicationSettingsService _applicationSettingsService;

        [ResolveConstructor]
        public WorksheetPersistenceService(IOpenFileViewService openFileViewService, ISaveFileViewService saveFileViewService,
            IApplicationSettingsService applicationSettingsService)
        {
            if (openFileViewService == null) throw new ArgumentNullException("openFileViewService");
            if (saveFileViewService == null) throw new ArgumentNullException("saveFileViewService");
            if (applicationSettingsService == null) throw new ArgumentNullException("applicationSettingsService");

            _openFileViewService = openFileViewService;
            _applicationSettingsService = applicationSettingsService;
            _saveFileViewService = saveFileViewService;
        }

#region Implementation of IWorksheetPersistenceService

        public bool SaveWorksheet(Worksheet worksheet, out string fileName)
        {
            // by default
            fileName = null;

            // set up the service
            _saveFileViewService.DefaultExt = DEFAULT_EXT;
            _saveFileViewService.Filter = DEFAULT_FILTER;

            // we get the response
            var _response = _saveFileViewService.SaveFile();
            if (_response.Cancelled) return false;

            // we update the time
            worksheet.UpdatedOn = DateTime.Now;
            worksheet.Author = _applicationSettingsService.AuthorInfo.Name;

            // we serialize
            var _worksheetXml = Serializer.Serialize(worksheet);
            fileName = _response.FileName;

            // and write
            using (var _fileStream = _response.StreamOpener())
            {
                using (var _writerStream = new StreamWriter(_fileStream))
                {
                    _writerStream.Write(_worksheetXml);
                }
            }

            // and return
            worksheet.IsDirty = false;
            return true;
        }

        public Worksheet OpenWorksheet(out string fileName)
        {
            // by default
            fileName = null;

            // set up the service
            _openFileViewService.Multiselect = false;
            _openFileViewService.Filter = DEFAULT_FILTER;

            // and we get the response
            var _response = _openFileViewService.OpenFile();
            if (_response.Cancelled) return null;
            fileName = _response.File.Name;

            // and read
            using (var _fileStream = _response.File.OpenRead())
            {
                using (var _readerStream = new StreamReader(_fileStream))
                {
                    return Serializer.Deserialize<Worksheet>(_readerStream.ReadToEnd());
                }
            }
        }

#endregion

    }
}
